use salvo::prelude::*;
use salvo::conn::rustls::{Keycert, RustlsConfig};
pub mod router;
pub mod handler;
pub mod utils;
pub mod middleware;
pub mod core;
use salvo::catch_panic::CatchPanic;
use crate::router::build_router; // 导入 build_router 函数

/// Create the application router with predefined routes
pub fn create_app_router() -> Router {
    Router::new()
        .hoop(CatchPanic::new()) // 添加全局捕获 panic 的中间件
        .hoop(middleware::LogMiddleware) // 添加日志中间件
        .push(build_router()) // 添加 router下的路由
}

/// Start the server with the given router on the specified address
pub async fn start_server(router: Router, addr: &'static str, port: u16) {
    // 加载环境变量
    dotenvy::dotenv().ok();
    // 初始化 rustls crypto provider (必须在使用 rustls 之前调用)
    rustls::crypto::aws_lc_rs::default_provider()
        .install_default()
        .expect("Failed to install rustls crypto provider");
    
    // 初始化日志系统，设置日志级别为 INFO
    let log_level = match std::env::var("LOG_LEVEL") {
        Ok(val) if val == "trace" => tracing::Level::TRACE,
        Ok(val) if val == "debug" => tracing::Level::DEBUG,
        Ok(val) if val == "info"  => tracing::Level::INFO,
        Ok(val) if val == "warn"  => tracing::Level::WARN,
        Ok(val) if val == "error" => tracing::Level::ERROR,
        _ => tracing::Level::INFO,
    };
    let _guard = utils::log::init_tracing_subscriber(log_level);

    // Load TLS certificate and private key from embedded PEM files
    let cert = include_bytes!("../certs/cert.pem").to_vec();
    let key = include_bytes!("../certs/key.pem").to_vec();

    // Configure TLS settings using Rustls
    let config = RustlsConfig::new(Keycert::new().cert(cert.as_slice()).key(key.as_slice()));

    // Create TCP listener with TLS encryption on port 5800
    let listener = TcpListener::new((addr, port)).rustls(config.clone());

    // Create QUIC listener and combine with TCP listener
    let acceptor = QuinnListener::new(config, (addr, port))
        .join(listener)
        .bind()
        .await;

    // 服务器实例
    let server = Server::new(acceptor);

    // Graceful shutdown
    let handler = server.handle();
    
    // 启动服务器
    tokio::select! {
        _ = tokio::signal::ctrl_c() => {
            tracing::warn!("收到 Ctrl+C 信号，开始优雅关闭");
            handler.stop_graceful(std::time::Duration::from_secs(10));
        }
        _ = server.serve(router) => {
            // running
        }
    }
    tracing::info!("Server 已停止");
}

